﻿using Roton.Engine.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Roton.Engine.Structures.ZZT
{
    static class ZZTConfig
    {
        static public BoardMemoryMap GetBoardMemoryMap(Block block)
        {
            BoardMemoryMap map = new BoardMemoryMap();
            map.ExitNorth = new BytePointer(block, 0x4569);
            map.ExitSouth = new BytePointer(block, 0x456A);
            map.ExitWest = new BytePointer(block, 0x456B);
            map.ExitEast = new BytePointer(block, 0x456C);
            map.RestartOnZap = new BytePointer(block, 0x456D);
            map.PlayerEnterX = new BytePointer(block, 0x45A9);
            map.PlayerEnterY = new BytePointer(block, 0x45AA);
            map.TimeLimit = new ShortPointer(block, 0x45AB);
            return map;
        }

        static public ElementMemoryMap GetElementMemoryMap(Block block, int index)
        {
            ElementMemoryMap map = new ElementMemoryMap();
            int offset = 0x4AD4 + (index * 0x00C3);
            map.Char = new BytePointer(block, offset + 0x0000);
            map.Color = new BytePointer(block, offset + 0x0001);
            map.Destructible = new BytePointer(block, offset + 0x0002);
            map.Pushable = new BytePointer(block, offset + 0x0003);
            map.Show = new BytePointer(block, offset + 0x0004);
            map.EditorFloor = new BytePointer(block, offset + 0x0005);
            map.Floor = new BytePointer(block, offset + 0x0006);
            map.CharCodeEnable = new BytePointer(block, offset + 0x0007);
            map.CharCode = new IntPointer(block, offset + 0x0008);
            map.Cycle = new ShortPointer(block, offset + 0x000C);
            map.ActionCode = new IntPointer(block, offset + 0x000E);
            map.InteractionCode = new IntPointer(block, offset + 0x0012);
            map.Menu = new ShortPointer(block, offset + 0x0016);
            map.Key = new BytePointer(block, offset + 0x0018);
            map.Name = new StringPointer(block, offset + 0x0019);
            map.Category = new StringPointer(block, offset + 0x002E);
            map.P1 = new StringPointer(block, offset + 0x0043);
            map.P2 = new StringPointer(block, offset + 0x0058);
            map.P3 = new StringPointer(block, offset + 0x006D);
            map.Board = new StringPointer(block, offset + 0x0082);
            map.Step = new StringPointer(block, offset + 0x0097);
            map.Code = new StringPointer(block, offset + 0x00AC);
            map.Points = new ShortPointer(block, offset + 0x00C1);
            return map;
        }

        static public GameMemoryMap GetGameMemoryMap(Block block)
        {
            GameMemoryMap map = new GameMemoryMap();
            map.AboutShown = new BytePointer(block, 0x7A60);
            map.ActIndex = new ShortPointer(block, 0x7406);
            map.AlertAmmo = new BytePointer(block, 0x4AAB);
            map.AlertDark = new BytePointer(block, 0x4AB1);
            map.AlertEnergy = new BytePointer(block, 0x4AB5);
            map.AlertFake = new BytePointer(block, 0x4AB3);
            map.AlertForest = new BytePointer(block, 0x4AB2);
            map.AlertGem = new BytePointer(block, 0x4AB4);
            map.AlertNoAmmo = new BytePointer(block, 0x4AAC);
            map.AlertNoShoot = new BytePointer(block, 0x4AAD);
            map.AlertNotDark = new BytePointer(block, 0x4AB0);
            map.AlertNoTorch = new BytePointer(block, 0x4AAF);
            map.AlertTorch = new BytePointer(block, 0x4AAE);
            map.BoardCount = new ShortPointer(block, 0x45BE);
            map.BorderColor = new BytePointer(block, 0x0073);
            map.BorderElement = new BytePointer(block, 0x0072);
            map.BorderTile = new ShortPointer(block, 0x0072);
            map.BreakGameLoop = new BytePointer(block, 0x4AC6);
            map.CancelScroll = new BytePointer(block, 0x7B66);
            map.DefaultBoardName = new StringPointer(block, 0x241E);
            map.DefaultSaveName = new StringPointer(block, 0x23EA);
            map.DefaultWorldName = new StringPointer(block, 0x2452);
            map.EdgeTile = new ShortPointer(block, 0x0074);
            map.EditorMode = new BytePointer(block, 0x740C);
            map.GameCycle = new ShortPointer(block, 0x7404);
            map.GameOver = new BytePointer(block, 0x7C8D);
            map.GamePaused = new BytePointer(block, 0x7408);
            map.GameQuiet = new BytePointer(block, 0x7C8C);
            map.GameSpeed = new BytePointer(block, 0x4ACE);
            map.GameWaitTime = new ShortPointer(block, 0x7402);
            map.Init = new BytePointer(block, 0x7B60);
            map.KeyArrow = new BytePointer(block, 0x7C7E);
            map.KeyPressed = new BytePointer(block, 0x7C70);
            map.KeyShift = new BytePointer(block, 0x7C6C);
            map.KeyVector = new ShortPointer(block, 0x7C68);
            map.KeyVectorX = new BytePointer(block, 0x7C68);
            map.KeyVectorY = new BytePointer(block, 0x7C69);
            map.LineChars = new StringPointer(block, 0x0098);
            map.Message = new StringPointer(block, 0x456E);
            map.OopByte = new BytePointer(block, 0x740E);
            map.OopNumber = new ShortPointer(block, 0x7426);
            map.OopWord = new StringPointer(block, 0x7410);
            map.PlayerElement = new BytePointer(block, 0x4AC8);
            map.QuitZZT = new BytePointer(block, 0x4AC5);
            map.SoundBuffer = new StringPointer(block, 0x7E90);
            map.SoundPlaying = new BytePointer(block, 0x7F9A);
            map.SoundPriority = new ShortPointer(block, 0x7C8E);
            map.SoundTicks = new BytePointer(block, 0x7E8F);
            map.StarChars = new StringPointer(block, 0x0336);
            map.StartBoard = new ShortPointer(block, 0x4ACA);
            map.ThingCount = new ShortPointer(block, 0x31CD);
            map.TransporterHChars = new StringPointer(block, 0x0236);
            map.TransporterVChars = new StringPointer(block, 0x0136);
            map.Vector4X = new ShortPointer(block, 0x0062);
            map.Vector4Y = new ShortPointer(block, 0x006A);
            map.Vector8X = new ShortPointer(block, 0x0042);
            map.Vector8Y = new ShortPointer(block, 0x0052);
            map.VisibleTileCount = new ShortPointer(block, 0x4ACC);
            map.WebChars = new StringPointer(block, -1);
            map.WorldFileName = new StringPointer(block, 0x23B6);
            map.WorldLoaded = new BytePointer(block, 0x7428);
            return map;
        }

        static public int GetMemorySize()
        {
            return 0x9610;
        }

        static public ThingMemoryMap GetThingMemoryMap(Block block, int index)
        {
            ThingMemoryMap map = new ThingMemoryMap();
            int offset = 0x31CF + (index * 0x0021);
            map.Cycle = new ShortPointer(block, offset + 0x0006);
            map.Follower = new ShortPointer(block, offset + 0x000B);
            map.Instruction = new ShortPointer(block, offset + 0x0015);
            map.Leader = new ShortPointer(block, offset + 0x000D);
            map.Length = new ShortPointer(block, offset + 0x0017);
            map.LocationX = new BytePointer(block, offset + 0x0000);
            map.LocationY = new BytePointer(block, offset + 0x0001);
            map.P1 = new BytePointer(block, offset + 0x0008);
            map.P2 = new BytePointer(block, offset + 0x0009);
            map.P3 = new BytePointer(block, offset + 0x000A);
            map.Pointer = new IntPointer(block, offset + 0x0011);
            map.StepX = new ShortPointer(block, offset + 0x0002);
            map.StepY = new ShortPointer(block, offset + 0x0004);
            map.UnderTile = new ShortPointer(block, offset + 0x000F);
            return map;
        }

        static public WorldMemoryMap GetWorldMemoryMap(Block block)
        {
            WorldMemoryMap map = new WorldMemoryMap();
            map.Ammo = new ShortPointer(block, 0x481E);
            map.Board = new ShortPointer(block, 0x482B);
            map.EnergyCycles = new ShortPointer(block, 0x4831);
            map.Flags = new StringPointer[]
            {
                new StringPointer(block, 0x4837),
                new StringPointer(block, 0x484C),
                new StringPointer(block, 0x4861),
                new StringPointer(block, 0x4876),
                new StringPointer(block, 0x488B),
                new StringPointer(block, 0x48A0),
                new StringPointer(block, 0x48B5),
                new StringPointer(block, 0x48CA),
                new StringPointer(block, 0x48DF),
                new StringPointer(block, 0x48F4),
                new StringPointer(block, 0x4909),
            };
            map.Gems = new ShortPointer(block, 0x4820);
            map.Health = new ShortPointer(block, 0x4829);
            map.Keys = new BytePointer(block, 0x4822);
            map.Locked = new BytePointer(block, 0x4922);
            map.Score = new ShortPointer(block, 0x4835);
            map.Stones = new ShortPointer(block, -1);
            map.TimePassed = new ShortPointer(block, 0x491E);
            map.TorchCycles = new ShortPointer(block, 0x482F);
            map.Torches = new ShortPointer(block, 0x482D);
            return map;
        }
    }
}
